<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1">
    <meta name="referrer" content="never">
    <title>新型动画</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }

        .box, .inner{
            position: absolute;
            top: 50px;
            left: 50px;
            width: 150px;
            height: 150px;
            background-color: #f00;
        }

        .inner {
            top: 230px;
            border-radius: 50%;
        }
    </style>
</head>
<body>
    <div class="box">
        box
    </div>

    <div class="inner">inner</div>
    <script type="text/javascript">
        // 控制动画进程是通过设置步长来实现的，新的控制动画进程方式：通过时间控制
        // 时间与进程的比例来实现动画的复杂控制
        /* 
            动画已过时间         动画已走进程
        ------------------- = ---------------- = k
             动画总时长           动画总进程
        */

        var box = document.querySelector(".box"),
            inner = document.querySelector(".inner"),
            duration = 2000; // 设定总时长

        box.onclick = function (){
            // 记录开始运动时间
            var startTime = Date.now();
            var timer = setInterval(function (){
                // 获取当前时间
                var now = Date.now();
                // 求出时间差值
                var timeGo = now - startTime;
                // 求出已过时间与总时长的比例
                var bite = timeGo / duration;
                console.log(bite);
                // 修正比例
                if(bite >= 1){
                    bite = 1;
                }
                // 元素运动
                box.style.left = 50 + 550 * bite + "px";
                if(bite == 1){
                    clearInterval(timer);
                }
            }, 1000/60);
        }


        /* inner.onclick = function (){
            // 获取性能时间戳起始值
            var startTime = performance.now();
            requestAnimationFrame(fn);
            // raf 函数参数函数自带一个性能时间戳
            function fn(now){
                // now => performance.now()
                var passTime = now - startTime;
                // 求比例
                var percent = passTime / duration;
                if(percent >= 1){
                    percent = 1;
                }
                // 元素运动
                inner.style.left = 50 + 550 * percent + "px";
                if(percent < 1){
                    requestAnimationFrame(fn);
                }
            }
        } */

        inner.onclick = function (){
            animate(1500, makeReverse(bounce), function (bite){
                inner.style.top = 230 + 300 * bite + "px";
            })
        }

        function animate(duration, timingFunction, callback){
            // 获取性能时间戳起始值
            var startTime = performance.now();
            requestAnimationFrame(fn);
            // raf 函数参数函数自带一个性能时间戳
            function fn(now){
                // now => performance.now()
                var passTime = now - startTime;
                // 求比例
                var percent = passTime / duration;
                if(percent >= 1){
                    percent = 1;
                }
                // 元素运动
                callback(timingFunction(percent));

                if(percent < 1){
                    requestAnimationFrame(fn);
                }
            }
        }

        function pow2x(x){
            return x * x;
        }

        // 弓箭射击  x表示弹性系数
        function back( bite){
            return Math.pow(bite, 2) * ((3+1) * bite - 3);
        }

        // 弹跳动画
        function bounce(bite){
            for(var a = 0,b = 1, result; 1; a += b, b/= 2){
                if(bite >= (7 - 4 * a) / 11){
                    return -Math.pow((11 - 6 * a - 11 * bite) / 4, 2) + Math.pow(b, 2);
                }
            }
        }

        // 逆反函数
        function makeReverse(timingFunction) {
            return function(bite) {
                return 1 - timingFunction(1 - bite);
            }
        }
    </script>
</body>
</html>